import { URLS } from '@akinon/next/data/urls'; import { Metadata, AsyncPageProps } from '@akinon/next/types'; import logger from '@akinon/next/utils/log'; import { notFound } from 'next/navigation'; type PrettyUrlResult = { matched: boolean; path?: string; pk?: number; }; const resolvePrettyUrlHandler = (pathname: string, ip: string | null) => async () => { let results = [] as { old_path: string }[]; let prettyUrlResult: PrettyUrlResult = { matched: false }; try { const requestUrl = URLS.misc.prettyUrls(`/${pathname}/`); logger.debug(`Resolving pretty url`, { pathname, requestUrl, ip }); const start = Date.now(); const apiResponse = await fetch(requestUrl, { next: { revalidate: 0 } }); const data = await apiResponse.json(); ({ results } = data); const end = Date.now(); console.warn('Pretty url response time', end - start, requestUrl); const matched = results.length > 0; const [{ old_path: path } = { old_path: '' }] = results; let pk; if (matched) { const pkRegex = /\/(\d+)\/$/; const match = path.match(pkRegex); pk = match ? parseInt(match[1]) : undefined; } prettyUrlResult = { matched, path, pk }; logger.trace('Pretty url result', { prettyUrlResult, ip }); } catch (error) { logger.error('Error resolving pretty url', { error, pathname, ip }); } return prettyUrlResult; }; export async function generateMetadata(props: AsyncPageProps) { const params = await props.params; let result: Metadata = {}; const { prettyurl } = params; const pageSlug = prettyurl .filter((x) => !x.startsWith('searchparams')) .join('/'); const searchParams = new URLSearchParams( decodeURIComponent( prettyurl .find((x) => x.startsWith('searchparams')) ?.replace('searchparams%7C', '') ) ?? {} ); const prettyUrlResult = await resolvePrettyUrlHandler(pageSlug, null)(); if (!prettyUrlResult.matched) { return notFound(); } const commonProps = { params: Promise.resolve({ ...params, pk: prettyUrlResult.pk }), searchParams: Promise.resolve(searchParams) }; try { if (prettyUrlResult.path.startsWith('/product/')) { await import('@product/[pk]/page').then(async (module) => { result = await module['generateMetadata']?.(commonProps as any); }); } if (prettyUrlResult.path.startsWith('/group-product/')) { await import('@group-product/[pk]/page').then(async (module) => { result = await module['generateMetadata']?.(commonProps as any); }); } if (prettyUrlResult.path.startsWith('/category/')) { await import('@category/[pk]/page').then(async (module) => { result = await module['generateMetadata']?.(commonProps as any); }); } if (prettyUrlResult.path.startsWith('/special-page/')) { await import('@special-page/[pk]/page').then(async (module) => { result = await module['generateMetadata']?.(commonProps as any); }); } if (prettyUrlResult.path.startsWith('/flat-page/')) { await import('@flat-page/[pk]/page').then(async (module) => { result = await module['generateMetadata']?.(commonProps as any); }); } // eslint-disable-next-line no-empty } catch (error) {} return result; } export const dynamic = 'force-static'; export const revalidate = 300; export default async function Page(props) { const params = await props.params; const { prettyurl } = params; const pageSlug = prettyurl .filter((x) => !x.startsWith('searchparams')) .join('/'); const urlSearchParams = new URLSearchParams( decodeURIComponent( prettyurl .find((x) => x.startsWith('searchparams')) ?.replace('searchparams%7C', '') ) ?? {} ); const searchParams = {}; for (const [key, value] of urlSearchParams.entries() as unknown as Array< [string, string] >) { if (!searchParams[key]) { searchParams[key] = []; } searchParams[key].push(value); } const result = await resolvePrettyUrlHandler(pageSlug, null)(); if (!result.matched) { return notFound(); } const commonProps = { params: { ...params, pk: result.pk }, searchParams: urlSearchParams } as any; if (result.path.startsWith('/category/')) { const CategoryPage = (await import('@category/[pk]/page')).default; return ; } if (result.path.startsWith('/product/')) { const ProductPage = (await import('@product/[pk]/page')).default; return ; } if (result.path.startsWith('/group-product/')) { const GroupProduct = (await import('@group-product/[pk]/page')).default; return ; } if (result.path.startsWith('/special-page/')) { const SpecialPage = (await import('@special-page/[pk]/page')).default; return ; } if (result.path.startsWith('/flat-page/')) { const FlatPage = (await import('@flat-page/[pk]/page')).default; return ; } return null; }